home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 2
/
Atari Mega Archive CD - Volume 2.iso
/
minix
/
up1510b.tgz
/
up1510b
/
src
/
commands
/
make
/
input.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-15
|
10KB
|
402 lines
/*************************************************************************
*
* m a k e : i n p u t . c
*
* Parse a makefile
*========================================================================
* Edition history
*
* # Date Comments By
* --- -------- ---------------------------------------------------- ---
* 1 ?? ??
* 2 23.08.89 new name tree structure introduced to speed up make,
* testname introduced to shrink the memory usage RAL
* 3 30.08.89 indention changed PSH,RAL
* 4 03.09.89 fixed LZ eliminated RAL
* 5 06.09.89 ; command added RAL
* ------------ Version 2.0 released ------------------------------- RAL
*
*************************************************************************/
#include "h.h"
static struct name *lastrrp;
static struct name *freerp = (struct name *)NULL;
void init()
{
if( (suffparray = (struct name **) malloc( sizesuffarray *
sizeof(struct name *))) == (struct name **) NULL)
fatal("No memory for suffarray",(char *)0,0);
if ((*suffparray = (struct name *)malloc(sizeof (struct name)))
== (struct name *)0)
fatal("No memory for name",(char *)0,0);
(*suffparray)->n_next = (struct name *)0;
if ((str1 = malloc(LZ1)) == (char *)0)
fatal("No memory for str1",(char *)0,0);
str1s.ptr = &str1;
str1s.len = LZ1;
if ((str2 = malloc(LZ2)) == (char *)0)
fatal("No memory for str2",(char *)0,0);
str2s.ptr = &str2;
str2s.len = LZ2;
}
void strrealloc(strs)
struct str *strs;
{
strs->len *= 2;
if( (*strs->ptr = realloc( *strs->ptr, strs->len)) == (char *) NULL)
fatal("No memory for string reallocation",(char *)0,0);
}
/*
* Intern a name. Return a pointer to the name struct
*/
struct name *newname(name)
char *name;
{
register struct name *rp;
register struct name *rrp;
register char *cp;
register int i;
register char *suff; /* ptr. to suffix in current name */
register struct name **sp; /* ptr. to ptr. to chain of names */
if ( (suff = suffix(name)) != (char *)NULL) {
for (i = 1, sp = suffparray, sp++;
i <= maxsuffarray && strcmp(suff, (*sp)->n_name) != 0;
sp++,i++);
if (i > maxsuffarray) {
if ( i >= sizesuffarray) { /* must realloc suffarray */
sizesuffarray *= 2;
if( (suffparray = (struct name **) realloc((char *) suffparray,
sizesuffarray * sizeof(struct name *))) == (struct name **) NULL)
fatal("No memory for suffarray",(char *)0,0);
}
maxsuffarray++;
sp = &suffparray[i];
if ((*sp = (struct name *)malloc(sizeof (struct name)))
== (struct name *)0)
fatal("No memory for name",(char *)0,0);
(*sp)->n_next = (struct name *)0;
if ((cp = malloc(strlen(suff)+1)) == (char *)0)
fatal("No memory for name",(char *)0,0);
strcpy(cp, suff);
(*sp)->n_name = cp;
}
}
else
sp = suffparray;
for ( rp = (*sp)->n_next, rrp = *sp; rp; rp = rp->n_next, rrp = rrp->n_next )
if (strcmp(name, rp->n_name) == 0) return rp;
if ( freerp == (struct name *)NULL) {
if ((rp = (struct name *)malloc(sizeof (struct name))) == (struct name *)0)
fatal("No memory for name",(char *)0,0);
}
else {
rp = freerp;
freerp = (struct name *)NULL;
}
rrp->n_next = rp;
rp->n_next = (struct name *)0;
if ((cp = malloc(strlen(name)+1)) == (char *)0)
fatal("No memory for name",(char *)0,0);
strcpy(cp, name);
rp->n_name = cp;
rp->n_line = (struct line *)0;
rp->n_time = (time_t)0;
rp->n_flag = 0;
lastrrp = rrp;
return rp;
}
/*
* Test a name.
* If the name already exists return the ptr. to its name structure.
* Else if the file exists 'intern' the name and return the ptr.
* Otherwise don't waste memory and return a NULL pointer
*/
struct name *testname(name)
char *name;
{
register struct name *rp;
lastrrp = (struct name *)NULL;
rp = newname( name);
if (rp->n_line || rp->n_flag & N_EXISTS)
return(rp);
modtime(rp);
if (rp->n_flag & N_EXISTS)
return(rp);
if (lastrrp != (struct name *)NULL) {
free (rp->n_name);
lastrrp->n_next = (struct name *)NULL;
freerp = rp;
}
return((struct name *)NULL);
}
/*
* Add a dependant to the end of the supplied list of dependants.
* Return the new head pointer for that list.
*/
struct depend *newdep(np, dp)
struct name *np;
struct depend *dp;
{
register struct depend *rp;
register struct depend *rrp;
if ((rp = (struct depend *)malloc(sizeof (struct depend)))
== (struct depend *)0)
fatal("No memory for dependant",(char *)0,0);
rp->d_next = (struct depend *)0;
rp->d_name = np;
if (dp == (struct depend *)0) return rp;
for (rrp = dp; rrp->d_next; rrp = rrp->d_next) ;
rrp->d_next = rp;
return dp;
}
/*
* Add a command to the end of the supplied list of commands.
* Return the new head pointer for that list.
*/
struct cmd *newcmd(str, cp)
char *str;
struct cmd *cp;
{
register struct cmd *rp;
register struct cmd *rrp;
register char *rcp;
if (rcp = strrchr(str, '\n')) *rcp = '\0'; /* Loose newline */
while (isspace(*str)) str++;
if (*str == '\0') return cp; /* If nothing left, the exit */
if ((rp = (struct cmd *)malloc(sizeof (struct cmd))) == (struct cmd *)0)
fatal("No memory for command",(char *)0,0);
rp->c_next = (struct cmd *)0;
if ((rcp = malloc(strlen(str)+1)) == (char *)0)
fatal("No memory for command",(char *)0,0);
strcpy(rcp, str);
rp->c_cmd = rcp;
if (cp == (struct cmd *)0) return rp;
for (rrp = cp; rrp->c_next; rrp = rrp->c_next) ;
rrp->c_next = rp;
return cp;
}
/*
* Add a new 'line' of stuff to a target. This check to see
* if commands already exist for the target. If flag is set,
* the line is a double colon target.
*
* Kludges:
* i) If the new name begins with a '.', and there are no dependents,
* then the target must cease to be a target. This is for .SUFFIXES.
* ii) If the new name begins with a '.', with no dependents and has
* commands, then replace the current commands. This is for
* redefining commands for a default rule.
* Neither of these free the space used by dependents or commands,
* since they could be used by another target.
*/
void newline(np, dp, cp, flag)
struct name *np;
struct depend *dp;
struct cmd *cp;
int flag;
{
bool hascmds = FALSE; /* Target has commands */
register struct line *rp;
register struct line *rrp;
/* Handle the .SUFFIXES case */
if (np->n_name[0] == '.' && !dp && !cp) {
for (rp = np->n_line; rp; rp = rrp) {
rrp = rp->l_next;
free(rp);
}
np->n_line = (struct line *)0;
np->n_flag &= ~N_TARG;
return;
}
/* This loop must happen since rrp is used later. */
for ( rp = np->n_line, rrp = (struct line *)0; rp; rrp = rp, rp = rp->l_next)
if (rp->l_cmd) hascmds = TRUE;
if (hascmds && cp && !(np->n_flag & N_DOUBLE))
/* Handle the implicit rules redefinition case */
if (np->n_name[0] == '.' && dp == (struct depend *)0) {
np->n_line->l_cmd = cp;
return;
}
else
error("Commands defined twice for target %s", np->n_name);
if (np->n_flag & N_TARG)
if (!(np->n_flag & N_DOUBLE) != !flag) /* like xor */
error("Inconsistent rules for target %s", np->n_name);
if ((rp = (struct line *)malloc(sizeof (struct line))) == (struct line *)0)
fatal("No memory for line",(char *)0,0);
rp->l_next = (struct line *)0;
rp->l_dep = dp;
rp->l_cmd = cp;
if (rrp)
rrp->l_next = rp;
else
np->n_line = rp;
np->n_flag |= N_TARG;
if (flag) np->n_flag |= N_DOUBLE;
}
/*
* Parse input from the makefile, and construct a tree structure
* of it.
*/
void input(fd)
FILE *fd;
{
char *p; /* General */
char *q;
register char *a;
st